package com.eclipse.training.ui;

import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;

import com.eclipse.training.Utils;
import com.eclipse.training.model.Asteroid;
import com.eclipse.training.model.DarkMatter;
import com.eclipse.training.model.Galaxy;
import com.eclipse.training.model.GalaxyCluster;
import com.eclipse.training.model.Nebula;
import com.eclipse.training.model.Planet;
import com.eclipse.training.model.Satellite;
import com.eclipse.training.model.SolarSystem;
import com.eclipse.training.model.Star;
import com.eclipse.training.model.StarCluster;
import com.eclipse.training.model.Universe;

public class UniverseTreeContentProvider implements ITreeContentProvider {

	@Override
	public void dispose() {
	}

	@Override
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
	}

	@Override
	public Object[] getElements(Object inputElement) {
		if (inputElement instanceof Universe) {
			Object[] cG = ((Universe) inputElement).getGalaxiesClusters()
					.toArray();
			Object[] dM = new Object[] { ((Universe) inputElement)
					.getDarkMatter() };

			return Utils.concat(cG, dM);
		}
		return null;
	}

	@Override
	public Object[] getChildren(Object parentElement) {
		if (parentElement instanceof Asteroid) {
			return null;
		} else if (parentElement instanceof DarkMatter) {
			return null;
		} else if (parentElement instanceof Galaxy) {
			Object[] s = ((Galaxy) parentElement).getStars().toArray();
			Object[] sC = ((Galaxy) parentElement).getStarClusters().toArray();
			Object[] n = ((Galaxy) parentElement).getNebulae().toArray();
			return Utils.concat(s, Utils.concat(sC, n));
		} else if (parentElement instanceof GalaxyCluster) {
			return ((GalaxyCluster) parentElement).getGalaxies().toArray();
		} else if (parentElement instanceof Nebula) {
			return null;
		} else if (parentElement instanceof Planet) {
			return ((Planet) parentElement).getSatellites().toArray();
		} else if (parentElement instanceof Satellite) {
			return null;
		} else if (parentElement instanceof SolarSystem) {
			Object[] a = ((SolarSystem) parentElement).getAsteroids().toArray();
			Object[] p = ((SolarSystem) parentElement).getPlanets().toArray();
			Object[] s = ((SolarSystem) parentElement).getStars().toArray();
			return Utils.concat(a, Utils.concat(p, s));
		} else if (parentElement instanceof Star) {
			return new Object[] { ((Star) parentElement).getSystems() };
		} else if (parentElement instanceof StarCluster) {
			return ((StarCluster) parentElement).getStars().toArray();
		}

		return null;
	}

	@Override
	public Object getParent(Object element) {
		return null;
	}

	@Override
	public boolean hasChildren(Object element) {
		if (element instanceof Asteroid) {
			return false;
		} else if (element instanceof DarkMatter) {
			return false;
		} else if (element instanceof Galaxy) {
			Object[] s = ((Galaxy) element).getStars().toArray();
			Object[] sC = ((Galaxy) element).getStarClusters().toArray();
			Object[] n = ((Galaxy) element).getNebulae().toArray();
			return Utils.concat(s, Utils.concat(sC, n)).length > 0;
		} else if (element instanceof GalaxyCluster) {
			return ((GalaxyCluster) element).getGalaxies().size() > 0;
		} else if (element instanceof Nebula) {
			return false;
		} else if (element instanceof Planet) {
			return ((Planet) element).getSatellites().size() > 0;
		} else if (element instanceof Satellite) {
			return false;
		} else if (element instanceof SolarSystem) {
			Object[] a = ((SolarSystem) element).getAsteroids().toArray();
			Object[] p = ((SolarSystem) element).getPlanets().toArray();
			Object[] s = ((SolarSystem) element).getStars().toArray();
			return Utils.concat(a, Utils.concat(p, s)).length > 0;
		} else if (element instanceof Star) {
			return ((Star) element).getSystems() != null;
		} else if (element instanceof StarCluster) {
			if (((StarCluster) element).getStars() != null)
				return ((StarCluster) element).getStars().size() > 0;
			else
				return false;
		}
		return false;
	}
}
